package com.sjz.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.sjz.dao.UserDao;
import com.sjz.utils.TransactionManager;


@Service
public class UserService {
	
	@Autowired
	private UserDao userDao;
	
	  @Autowired
	  private TransactionManager transactionManager;
	  
	  @Autowired
	  private LogService logService;
	  
	  
	  /****
	   * logService和add都是使用REQUIRED  两张表 都不会插入
	   * logService 不添加事务     add使用REQUIRED  两张表 都不会插入
	   */
	  @Transactional(propagation=Propagation.REQUIRED)
	  public void add() {
				logService.addLog();
				userDao.add("lisi", 18);
				int i = 1 / 0;// 可能会发生异常
			 
		}
	  
	  
	  /****
	   * logService这个不加事务
	   * NEVER  以非事务方式执行操作，如果当前存在事务，就把当前事务挂起。 
	   * 两个都会插入数据
	   */
	  @Transactional(propagation=Propagation.NEVER)
	  public void add16() {
				logService.addLog();
				userDao.add("lisi", 18);
				int i = 1 / 0;// 可能会发生异常
			 
		}
	  
	  /****
	   * logService这个不加事务
	   * NOT_SUPPORTED  以非事务方式执行操作，如果当前存在事务，就把当前事务挂起。 
	   * 两个都会插入数据
	   */
	  @Transactional(propagation=Propagation.NOT_SUPPORTED)
	  public void add15() {
				logService.addLog();
				userDao.add("lisi", 18);
				int i = 1 / 0;// 可能会发生异常
			 
		}
	  
	  /****
	   * logService这个不加事务
	   * No existing transaction found for transaction marked with propagation 'mandatory' 
	   * 两个都不会插入数据
	   */
	  @Transactional(propagation=Propagation.MANDATORY)
	  public void add14() {
				logService.addLog();
				userDao.add("lisi", 18);
				int i = 1 / 0;// 可能会发生异常
			 
		}
	  
	  /****
	   * logService这个不加事务
	   * 两条数据都会插入    SUPPORTS 支持当前事务，如果当前没有事务，就以非事务方式执行。 
	   * 这里不会管logService的操作是否异常
	   */
	  @Transactional(propagation=Propagation.SUPPORTS)
	  public void add13() {
				logService.addLog();
				userDao.add("lisi", 18);
				int i = 1 / 0;// 可能会发生异常
			 
		}
	  
	  /***
	   * logService这个不加事务
	   * 两张表都会存数据
	   */
	  @Transactional(propagation=Propagation.REQUIRES_NEW)
	  public void add12() {
				try {
					logService.addLog();
					userDao.add("lisi", 18);
					int i = 1 / 0;// 可能会发生异常
				} catch (Exception e) {
				}
			 
		}
	  
	  /*****
	   * logService这个不加事务  add方法使用REQUIRES_NEW（新建事务，如果当前存在事务，把当前事务挂起。 ）
	   * 测试的结果是两个表都不会保存数据
	   */
	  @Transactional(propagation=Propagation.REQUIRES_NEW)
	  public void add11() {
				logService.addLog();
				userDao.add("lisi", 18);
				int i = 1 / 0;// 可能会发生异常
			 
		}
	  
	  /****
		 * 测试两个事务都是propagation=Propagation.REQUIRES_NEW 
		 * 并且捕获异常  两条语句都可以捕获 
		 */
	  @Transactional(propagation=Propagation.REQUIRES_NEW)
	  public void add10() {
		try {
			logService.addLog();
			userDao.add("lisi", 18);
			int i = 1 / 0;// 可能会发生异常
		} catch (Exception e) {
			 
		}
	}
	  
	        /****
			 * 测试两个事务都是propagation=Propagation.REQUIRES_NEW 
			 * 不捕获异常  日志数据表保存  user数据不保存数据
			 */
	  @Transactional(propagation=Propagation.REQUIRES_NEW)
	  public void add9() {
		logService.addLog();
		userDao.add("lisi", 18);
		int i = 1 / 0;// 可能会发生异常
	}
	  
	  /***
	   * try catch的话。需要手动回滚  和xml事物的方式类似
	   */
	  @Transactional
	  public void add8() {
		  try {
				 userDao.add("lisi", 18);
				 int i=1/0;//可能会发生异常
				 userDao.add("qq", 19);
			} catch (Exception e) { 
				//声明式事物 如果捕获异常的话，需要手动来回滚
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
		}
	  
	  /***
	   * try catch的话。如果报错的话，一条保存成功
	   */
	  @Transactional
	  public void add7() {
		  try {
				 userDao.add("lisi", 18);
				 int i=1/0;//可能会发生异常
				 userDao.add("qq", 19);
			} catch (Exception e) { 
			}
		}
	  
	  /***
	   * 使用事物不会保存一条数据
	   */
	  @Transactional
	  public void add6() {
			 userDao.add("lisi", 18);
			  int i=1/0;//可能会发生异常
			 userDao.add("qq", 19);
		}
	  
	  /***
	   * 如果使用声明式事物的话，需要手动回滚  一条数据也不保存了
	   */
	  public void add5() {
			try {
				 userDao.add("lisi", 18);
				 int i=1/0;//可能会发生异常
				 userDao.add("qq", 19);
			} catch (Exception e) {
				//声明式事物 如果捕获异常的话，需要手动来回滚
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
		}
	  
	  /***
	   * 如果使用声明式事物的话，如果报错的话，一条保存成功
	   */
	  public void add4() {
			try {
				 userDao.add("lisi", 18);
				 int i=1/0;//可能会发生异常
				 userDao.add("qq", 19);
			} catch (Exception e) {
				 
			}
		}
	
	  /****
	   * 如果使用声明式事物的话，如果报错的话，全部失败。
	   */
	public void add3() {
		 userDao.add("lisi", 18);
		// int i=1/0;//可能会发生异常
		 userDao.add("qq", 19);
	}
	
	/***
	 * 使用手动的方式来使用事物  如果一个报错另外一个也保存失败
	 */
	public void add2() {
		TransactionStatus transactionStatus = null;
		try {
			transactionStatus = transactionManager.begin();
			 userDao.add("lisi", 18);
			System.out.println("UserService####张三插入成功!");
			 int i = 1 / 0;// 是会发生运行异常.
			userDao.add("qq", 19);
			System.out.println("UserService####李四插入成功!");
			System.out.println("UserService####add方法执行完毕!");
			transactionManager.commit(transactionStatus);
		} catch (Exception e) {
			// 可能会发生异常,进行回滚.
			e.printStackTrace();
			if (transactionManager != null)
				transactionManager.rollback(transactionStatus);
		}
	}
	
	/****
	 * 如果不加事物这个有一个成功，一个执行失败
	 */
	public void add1() {
		  userDao.add("lisi", 18);
		 int i=1/0;//可能会发生异常
		 userDao.add("qqq", 19);
	}
}
